﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace Micro.Core.FrameWork.ORM.EntityFrameworkCore
{
    public class Repository<TEntity> : IRepository<TEntity> where TEntity : BaseModel
    {
        private readonly DbContext _dbContext;
        public Repository(DbContext dbContext) => _dbContext = dbContext;
        public void Add(TEntity obj)
        {
            _dbContext.Set<TEntity>().Add(obj);
        }

        public async Task AddAsync(TEntity obj)
        {
           await _dbContext.Set<TEntity>().AddAsync(obj);
        }

        public TEntity Get(Guid id)
        {
            return _dbContext.Set<TEntity>().FirstOrDefault(s => s.Id.Equals(id));
        }

        public IQueryable<TEntity> Get(Expression<Func<TEntity, bool>> prExpression)
        {
            return _dbContext.Set<TEntity>().Where(prExpression);
        }

        public IEnumerable<TEntity> Get()
        {
            return _dbContext.Set<TEntity>().AsEnumerable();
        }

        public async Task<TEntity> GetAsync(Guid id)
        {
            return await _dbContext.Set<TEntity>().Where(s => s.Id.Equals(id)).FirstOrDefaultAsync();
        }

        public async Task<TEntity> GetNoTrackingAsync(Guid id)
        {
            return await _dbContext.Set<TEntity>().AsNoTracking().Where(s => s.Id.Equals(id)).FirstOrDefaultAsync();
        }

        public Task RemoveAsync(TEntity obj)
        {
            obj.IsDelete = true;
            _dbContext.Set<TEntity>().Update(obj);
            return Task.CompletedTask;
        }

        public Task RemoveHardAsync(TEntity obj)
        {
            _dbContext.Set<TEntity>().Remove(obj);
            return Task.CompletedTask;
        }

        public int SaveChanges()
        {
            return _dbContext.SaveChanges();
        }

        public async Task<int> SaveChangesAsync()
        {
            return await _dbContext.SaveChangesAsync();
        }
    }
}
